/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.udt.designtime.manager.validate;


import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.CommonDtmCollection;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspAssociationKey;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.designtime.api.element.GspEnumValue;
import com.inspur.edp.cef.designtime.api.operation.CommonDetermination;
import com.inspur.edp.cef.designtime.api.operation.CommonOperation;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import com.inspur.edp.udt.designtime.api.entity.element.ElementCollection;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.designtime.api.entity.validation.UdtTriggerTimePointType;
import com.inspur.edp.udt.designtime.api.entity.validation.ValidationCollection;
import com.inspur.edp.udt.designtime.api.entity.validation.ValidationInfo;
import com.inspur.edp.udt.designtime.api.utils.UdtUtils;
import com.inspur.edp.udt.designtime.manager.udtmanagerexception.UdtManagerException;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import java.text.DateFormat;
import java.util.EnumSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UdtValidater {

  private static final String BE_VALIDATOR_EXCEPTION = "UdtValidater";

  /**
   * 业务字段校验
   * @param udt
   */
  public final void validate(UnifiedDataTypeDef udt) {
    String validateResult = validateUdt(udt);
    if (validateResult.length() > 0) {
      //保存前校验不通过，抛异常
      throw new UdtManagerException("", BE_VALIDATOR_EXCEPTION, validateResult, null,
          ExceptionLevel.Error, false);
    }
  }

  private String validateUdt(UnifiedDataTypeDef udt) {
    String message = validateBasicInfo(udt);
    if (message.length() > 0) {
      return message;
    }
    if (udt instanceof ComplexDataTypeDef) {
      message = validateComplexUdt(
          (ComplexDataTypeDef) ((udt instanceof ComplexDataTypeDef) ? udt : null));
      if (message.length() > 0) {
        return message;
      }
    } else if (udt instanceof SimpleDataTypeDef) {
      message = validateSimpleDataTypeDef((SimpleDataTypeDef) udt);
      if (message.length() > 0) {
        return message;
      }
    }

    message = validateValidations(udt);
    return message;
  }

  /**
   * 对UDT进行校验
   * @param element
   * @return
   */
  private String validateSimpleDataTypeDef(SimpleDataTypeDef element) {
    StringBuilder sb = new StringBuilder();
    if (element.getObjectType() == GspElementObjectType.Association) {
      //关联字段必须满足ID字段类型
      if (!validateIDElementTypeAndLength(element)) {
        sb.append(String.format(" [对象类型] 属性为关联, 应满足ID字段类型，字段数据类型为[字符串], 并且[长度]为36! "));
        sb.append("\n");
      }

      if (element.getChildAssociations() == null || element.getChildAssociations().size() < 1) {
        sb.append(String.format(" [对象类型] 属性为关联, [关联] 属性不允许为空! "));
        sb.append("\n");
      } else {

        for (GspAssociation association : element.getChildAssociations()) {
          if (association == null || association.getKeyCollection().size() == 0) {
            sb.append(String.format((" [对象类型] 属性为关联, [关联] 属性不允许为空! ")));
            sb.append("\n");
          }
          //处理有时关联字段会丢失的问题
          for (GspAssociationKey associationKey : association.getKeyCollection()) {
            if (associationKey.getSourceElement().length() == 0
                || associationKey.getTargetElement().length() == 0) {
              sb.append(String.format(("引用元素丢失! ")));
              sb.append("\n");
            }
          }
        }
      }
    } else if (element.getObjectType() == GspElementObjectType.Enum) {
      if (element.getContainEnumValues().size() == 0) {
        sb.append(String.format((" [对象类型] 属性为枚举, [枚举] 属性不允许为空! ")));
        sb.append("\n");
      }
      // 枚举类型字段，非必填
      if (element.getIsRequired()) {
        sb.append(String.format((" [对象类型] 属性为枚举, [是否必填] 属性应为否。")));
        sb.append("\n");
      }
      //处理Enum值必须为string的问题
      for (GspEnumValue ev : element.getContainEnumValues()) {
        String _value = ev.getValue();
        if (element.getMDataType() == GspElementDataType.Boolean) {
          try {
            boolean temp = Boolean.parseBoolean(_value);
          } catch (java.lang.Exception e) {
            sb.append(String.format((" [枚举] 属性中的枚举值应该为布尔值! ")));
            sb.append("\n");
          }
        } else if (element.getMDataType() == GspElementDataType.String) {
          int indexLength = String.valueOf(ev.getIndex()).length();
          int eleLength = element.getLength();
          if (eleLength < indexLength) {
            sb.append(String.format(" [枚举值]'%1$s' 中的索引长度应小于等于字段长度! ", ev.getName()));
            sb.append("\n");
          }
        }
      }
    } else {
      sb.append(String.format(
          validateElementDefaultValue(element.getContainElements().get(0), element.getCode(),
              "当前业务字段")));
    }
    return sb.toString();
  }

  /**
   * 校验基本信息
   * @param udt
   * @return
   */
  private String validateBasicInfo(UnifiedDataTypeDef udt) {
    StringBuilder sb = new StringBuilder();
    if (UdtUtils.checkNull(udt.getCode())) {
      sb.append(String.format("业务字段'%1$s'的编号不能为空! ", udt.getName()));
    } else {
      // 模型Code限制非法字符
      if (!conformToNaminGspecification(udt.getCode())) {
        sb.append(String
            .format("业务字段'%1$s'的 [编号] 属性必须以英文字母或下划线开头, 并且只能由英文字母、数字、下划线(_)组成! ", udt.getName()));
        sb.append("\n");
      }
    }

    if (UdtUtils.checkNull(udt.getName())) {
      sb.append(String.format("业务字段'%1$s'的名称不能为空! ", udt.getCode()));
    }

    return sb.toString();
  }

  private String validateComplexUdt(ComplexDataTypeDef udt) {
    return validateComplexBasicInfo(udt);

  }

  /**
   * 校验单值UDT
   * @param udt
   * @return
   */
  private String validateComplexBasicInfo(ComplexDataTypeDef udt) {
    StringBuilder sb = new StringBuilder();

    for (IGspCommonField el : udt.getElements()) {

      UdtElement element = (UdtElement) ((el instanceof UdtElement) ? el : null);
      if (UdtUtils.checkNull(element.getCode())) {
        sb.append(String
            .format("业务字段 '%1$s' 中字段 '%2$s' 的 [编号] 属性不允许为空! ", udt.getName(), element.getName()));
        sb.append("\n");
      } else {
        // 字段Code限制非法字符
        if (!conformToNaminGspecification(element.getCode())) {
          sb.append(String
              .format("业务字段 '%1$s' 中字段 '%2$s' 的 [编号] 属性必须以英文字母或下划线开头, 并且只能由英文字母、数字、下划线(_)组成! ",
                  udt.getName(), element.getName()));
          sb.append("\n");
        }
      }
      if (UdtUtils.checkNull(element.getName())) {
        sb.append(String
            .format("业务字段 '%1$s' 中字段 '%2$s'的 [名称] 属性不允许为空! ", udt.getName(), element.getCode()));
        sb.append("\n");
      }

      if (element.getObjectType() == GspElementObjectType.Association) {
        if (udt.getDbInfo().getMappingType() == ColumnMapType.SingleColumn) {
          throw new UdtManagerException("", BE_VALIDATOR_EXCEPTION,
              "当前值存储方式为[存为一列]，暂不支持设置字段关联，字段‘{element.Name}’对象类型为关联，请修改。", null,
              ExceptionLevel.Error, false
          );
        }

        //关联字段必须满足ID字段类型
        if (!validateIDElementTypeAndLength(element)) {
          sb.append(String
              .format("业务字段 '%1$s' 中字段 '%2$s'的 [对象类型] 属性为关联, 应满足ID字段类型，字段数据类型为[字符串], 并且[长度]为36! ",
                  udt.getName(), element.getName()));
          sb.append("\n");
        }

        if (element.getChildAssociations() == null || element.getChildAssociations().size() < 1) {
          sb.append(String
              .format("业务字段 '%1$s' 中字段 '%2$s'的 [对象类型] 属性为关联, [关联] 属性不允许为空! ", udt.getName(),
                  element.getName()));
          sb.append("\n");
        } else {

          for (GspAssociation association : element.getChildAssociations()) {
            if (association == null || association.getKeyCollection().size() == 0) {
              sb.append(String
                  .format("业务字段 '%1$s' 中字段 '%2$s'的 [对象类型] 属性为关联, [关联] 属性不允许为空! ", udt.getName(),
                      element.getName()));
              sb.append("\n");
            }
            //处理有时关联字段会丢失的问题
            for (GspAssociationKey associationKey : association.getKeyCollection()) {
              if (associationKey.getSourceElement().length() == 0
                  || associationKey.getTargetElement().length() == 0) {
                sb.append(String
                    .format("业务字段 '%1$s' 中字段 '%2$s'的引用元素丢失! ", udt.getName(), element.getName()));
                sb.append("\n");
              }
            }
          }
        }
      } else if (element.getObjectType() == GspElementObjectType.Enum) {
        if (element.getContainEnumValues().size() == 0) {
          sb.append(String
              .format("业务字段 '%1$s' 中字段 '%2$s'的 [对象类型] 属性为枚举, [枚举] 属性不允许为空! ", udt.getName(),
                  element.getName()));
          sb.append("\n");
        }
        // 枚举类型字段，非必填
        if (element.getIsRequire()) {
          sb.append(String.format((" [对象类型] 属性为枚举, [是否必填] 属性应为否。")));
          sb.append("\n");
        }
        //处理Enum值必须为string的问题
        for (GspEnumValue ev : element.getContainEnumValues()) {
          String _value = ev.getValue();
          if (element.getMDataType() == GspElementDataType.Boolean) {
            try {
              boolean temp = Boolean.parseBoolean(_value);
            } catch (java.lang.Exception e) {
              sb.append(String.format("业务字段 '%1$s' 中字段 '%2$s'的 [枚举] 属性中的枚举值应该为布尔值! ", udt.getName(),
                  element.getName()));
              sb.append("\n");
            }
          } else if (element.getMDataType() == GspElementDataType.String) {
            int indexLength = String.valueOf(ev.getIndex()).length();
            int eleLength = element.getLength();
            if (eleLength < indexLength) {
              sb.append(String
                  .format("业务字段 '%1$s' 中字段 '%2$s'的 [枚举值]'%3$s' 中的索引长度应小于等于字段长度! ", udt.getName(),
                      udt.getName(), ev.getName()));
              sb.append("\n");
            }
          }
        }

        if (element.getContainEnumValues() != null && element.getContainEnumValues().size() > 0) {
          for (int i = 0; i < element.getContainEnumValues().size() - 1; i++) {

            GspEnumValue enumValue1 = element.getContainEnumValues().get(i);
            for (int j = i + 1; j < element.getContainEnumValues().size(); j++) {

              GspEnumValue enumValue2 = element.getContainEnumValues().get(j);
              if (enumValue1.getName().equals(enumValue2.getName())) {
                sb.append(String.format("业务字段 '%1$s' 中字段 '%2$s'的枚举编号'%3$s'重复。", udt.getName(),
                    element.getName(), enumValue1.getName()));
                sb.append("\n");
              }
            }
          }
        }
      } else {
        sb.append(String
            .format((validateElementDefaultValue(element, udt.getCode(), "多值UDT'%1$s'中字段'%2$s'"))));
      }
      if (element.getIsUdt()) {
        if (udt.getDbInfo().getMappingType() == ColumnMapType.MultiColumns) {
          throw new UdtManagerException("", BE_VALIDATOR_EXCEPTION,
              "当前值存储方式为[存为多列]，暂不支持设置字段数据类型为[业务字段]，字段‘{element.Name}’引用了UDT，请修改。", null,
              ExceptionLevel.Error, false);
        }
      }
      if (element.getIsUdt() && UdtUtils.checkNull(element.getUdtID())) {
        sb.append(String.format("业务字段 '%1$s' 中字段 '%2$s'的数据类型为[业务字段]，请配置其对应的业务字段。", udt.getName(),
            element.getName()));
        sb.append("\n");
      }
    }

    String message = validateElementCodeRepeat(udt);
    if (message.length() > 0) {
      sb.append(String.format((message)));
    }

    String dtmMessage = validateCommonDeterminations(udt);
    if (dtmMessage.length() > 0) {
      sb.append(String.format((dtmMessage)));
    }
    return sb.toString();
  }

  /**
   * 字段编号重复
   */
  private String validateElementCodeRepeat(ComplexDataTypeDef udt) {
    ElementCollection allElementList = udt.getElements();
    if (allElementList != null && allElementList.size() > 0) {
      for (int i = 0; i < allElementList.size() - 1; i++) {
        UdtElement firstElement = (UdtElement) ((allElementList.getItem(i) instanceof UdtElement)
            ? allElementList.getItem(i) : null);
        for (int j = i + 1; j < allElementList.size(); j++) {
          UdtElement secondElement = (UdtElement) ((allElementList.getItem(j) instanceof UdtElement)
              ? allElementList.getItem(j) : null);
          if (firstElement.getCode().equals(secondElement.getCode())) {
            String message = String
                .format("字段 '%1$s' 和字段 '%2$s' 的 [编号] 属性不允许重复! ", firstElement.getName(),
                    secondElement.getName());
            return message;
          }
        }
      }
    }
    return "";
  }

  private String validateValidations(UnifiedDataTypeDef udt) {
    StringBuilder sb = new StringBuilder();

    ValidationCollection actions = udt.getValidations();

    String errorMessage = String.format("业务字段 '%1$s' 中的校验规则 ", udt.getName());
    //①必填项
    sb.append(String.format(validateValidationBasicInfo(errorMessage, actions)));
    if (sb.length() > 0) {
      return sb.toString();
    }
    //②编号重复
    sb.append(String.format((validateValidationCodeRepeat(errorMessage, actions))));
    //③校验规则至少选择一种执行时机
    sb.append(String.format(validateValidationTriggerTimePoint(errorMessage, actions)));

    return sb.toString();
  }

  /**
   * 校验规则至少选择一个执行时机
   */
  private String validateValidationTriggerTimePoint(String errorMessage,
      ValidationCollection operations) {
    StringBuilder sb = new StringBuilder();
    if (operations != null && operations.size() > 0) {
      for (int i = 0; i < operations.size(); i++) {
        if (operations.get(i).getTriggerTimePointType()
            .equals(EnumSet.of(UdtTriggerTimePointType.None))) {
          String message = String
              .format(errorMessage + operations.get(i).getName() + "的 [执行时机] 至少选择一种。");
          sb.append(message);
          sb.append("\n");
        }
      }
    }
    return sb.toString();
  }

  private String validateValidationBasicInfo(String errorMessage,
      ValidationCollection validations) {
    if (validations == null || validations.size() == 0) {
      return "";
    }

    StringBuilder sb = new StringBuilder();

    for (ValidationInfo val : validations) {
      if (UdtUtils.checkNull(val.getCode())) {
        sb.append(
            String.format(errorMessage + String.format("'%1$s'的 [编号] 属性不允许为空! ", val.getName())));
        sb.append("\n");
      } else {
        // 操作Code限制非法字符
        if (!conformToNaminGspecification(val.getCode())) {
          sb.append(String.format(errorMessage + String
              .format("'%1$s'的 [编号] 属性必须以英文字母或下划线开头, 并且只能由英文字母、数字、下划线(_)组成! ", val.getName())));
          sb.append("\n");
        }
      }
      if (UdtUtils.checkNull(val.getName())) {
        sb.append(
            String.format(errorMessage + String.format("'%1$s'的 [名称] 属性不允许为空! ", val.getCode())));
        sb.append("\n");
      }
    }
    return sb.toString();
  }

  private String validateValidationCodeRepeat(String errorMessage,
      ValidationCollection validations) {
    StringBuilder sb = new StringBuilder();
    if (validations != null && validations.size() > 0) {
      for (int i = 0; i < validations.size() - 1; i++) {

        ValidationInfo firstOperation = validations.get(i);
        for (int j = i + 1; j < validations.size(); j++) {

          ValidationInfo secondOperation = validations.get(j);
          if (firstOperation.getCode().equals(secondOperation.getCode())) {
            String message = String
                .format(errorMessage + "'%1$s'与'%2$s'的编号重复。", firstOperation.getName(),
                    secondOperation.getName());
            sb.append("\n");
            return message;
          }
        }
      }
    }
    return sb.toString();
  }

  private boolean conformToNaminGspecification(String text) {
    String regex = "^[A-Za-z_][A-Za-z_0-9]*$";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(text);
    boolean isMatch = matcher.matches();
    return isMatch;
  }

  private boolean validateIDElementTypeAndLength(UdtElement element) {
    if (element == null) {
      return true;
    }
    return element.getMDataType() == GspElementDataType.String && element.getLength() == 36;
  }

  private boolean validateIDElementTypeAndLength(SimpleDataTypeDef element) {
    if (element == null) {
      return true;
    }
    return element.getMDataType() == GspElementDataType.String && element.getLength() == 36;
  }


  private String validateElementDefaultValue(IGspCommonField ele, String objName,
      String errorMessage) {
    StringBuilder sb = new StringBuilder();
    String regex = "^-?\\\\d+$";//判断整数，负值也是整数
    Pattern pattern = Pattern.compile(regex);
    String reDecimalString = String
        .format("^(([0-9]+\\.[0-9]%1$s})|([0-9]*\\.[0-9]%1$s})|([1-9][0-9]+)|([0-9]))$",
            ele.getPrecision());
    Pattern patternDeciaml = Pattern.compile(regex);
    // 20190523-整型枚举可设置枚举编号为默认值；关联/udt默认值暂不支持；
    if (ele.getObjectType() != GspElementObjectType.None) {
      return sb.toString();
    }

    boolean isValidate = true;
    GspElementDataType type = ele.getMDataType();
    String value = ele.getDefaultValue();

    if (!UdtUtils.checkNull(value)) {
      switch (type) {
        case String:
        case Text:
          break;
        case Integer:
          Matcher matcherInt = pattern.matcher(value);
          if (matcherInt.matches()) {
            isValidate = true;
          } else {
            isValidate = false;
          }
          break;
        case Decimal:
          Matcher matcherDecimal = patternDeciaml.matcher(value);
          if (matcherDecimal.matches()) {
            isValidate = true;
          } else {
            //isValidate = false;
            sb.append(String
                .format(errorMessage + "的[默认值] 与[数据类型] 不匹配，请检查是否为[浮点数字]，请检查[精度]是否匹配! ", objName,
                    ele.getName()));
            sb.append("\n");
            return sb.toString();
          }
          break;
        case Date:
        case DateTime:
          try {
            java.util.Date dateTime = DateFormat.getInstance().parse(value);
            isValidate = true;
          } catch (java.lang.Exception e) {
            isValidate = false;
          }
          break;
        case Boolean:
          if (value.toUpperCase().equals("True".toUpperCase()) || value.toUpperCase()
              .equals("False".toUpperCase())) {
            isValidate = true;
          } else {
            isValidate = false;
          }
          break;
        case Binary:
          if (value.trim().equals("")) {
            isValidate = true;
          } else {
            isValidate = false;
          }
          break;
        default:
          break;
      }
    }
    if (!isValidate) {
      sb.append(String.format(errorMessage + "的 [默认值] 与 [数据类型] 不匹配! ", objName, ele.getName()));
      sb.append("\n");
    }
    return sb.toString();
  }

//C#
  ///#region 操作

  /**
   * 暂用udtValidation，不适用commonValidation
   */
  private String validateCommonValidations(ComplexDataTypeDef cUdt) {
    StringBuilder sb = new StringBuilder();
    CommonDtmCollection dtmsAfterCreate = cUdt.getDtmAfterCreate();
    CommonDtmCollection dtmsAfterModify = cUdt.getDtmAfterModify();
    CommonDtmCollection dtmsBeforeSave = cUdt.getDtmBeforeSave();
    java.util.ArrayList<CommonOperation> dtms = new java.util.ArrayList<CommonOperation>();

    for (CommonDetermination item : dtmsAfterCreate) {
      dtms.add(item);
    }

    for (CommonDetermination item : dtmsAfterModify) {
      dtms.add(item);
    }

    for (CommonDetermination item : dtmsBeforeSave) {
      dtms.add(item);
    }
    String errorMessage = String.format("业务字段 '%1$s' 中的校验规则 ", cUdt.getName());

    //①必填项
    sb.append(String.format(validateCommonOperationBasicInfo(errorMessage, dtms)));
    if (sb.length() > 0) {
      return sb.toString();
    }
    //②编号重复
    sb.append(String.format(validateCommonOperationCodeRepeat(errorMessage, dtms)));

    return sb.toString();
  }

  private String validateCommonDeterminations(ComplexDataTypeDef cUdt) {
    StringBuilder sb = new StringBuilder();
    CommonDtmCollection dtmsAfterCreate = cUdt.getDtmAfterCreate();
    CommonDtmCollection dtmsAfterModify = cUdt.getDtmAfterModify();
    CommonDtmCollection dtmsBeforeSave = cUdt.getDtmBeforeSave();
    java.util.ArrayList<CommonOperation> dtms = new java.util.ArrayList<CommonOperation>();

    for (CommonDetermination item : dtmsAfterCreate) {
      dtms.add(item);
    }

    for (CommonDetermination item : dtmsAfterModify) {
      dtms.add(item);
    }

    for (CommonDetermination item : dtmsBeforeSave) {
      dtms.add(item);
    }
    String errorMessage = String.format("业务字段 '%1$s' 中的联动计算 ", cUdt.getName());

    //①必填项
    sb.append(String.format((validateCommonOperationBasicInfo(errorMessage, dtms))));
    if (sb.length() > 0) {
      return sb.toString();
    }
    //②编号重复
    sb.append(String.format((validateCommonOperationCodeRepeat(errorMessage, dtms))));

    return sb.toString();
  }

  private String validateCommonOperationBasicInfo(String errorMessage,
      java.util.ArrayList<CommonOperation> ops) {
    if (ops == null || ops.isEmpty()) {
      return "";
    }

    StringBuilder sb = new StringBuilder();

    for (CommonOperation val : ops) {
      if (UdtUtils.checkNull(val.getCode())) {
        sb.append(
            String.format((errorMessage + String.format("'%1$s'的 [编号] 属性不允许为空! ", val.getName()))));
        sb.append("\n");
      } else {
        // 操作Code限制非法字符
        if (!conformToNaminGspecification(val.getCode())) {
          sb.append(String.format(errorMessage + String
              .format("'%1$s'的 [编号] 属性必须以英文字母或下划线开头, 并且只能由英文字母、数字、下划线(_)组成! ", val.getName())));
          sb.append("\n");
        }
      }
      if (UdtUtils.checkNull(val.getName())) {
        sb.append(
            String.format(errorMessage + String.format("'%1$s'的 [名称] 属性不允许为空! ", val.getCode())));
        sb.append("\n");
      }
    }
    return sb.toString();
  }

  private String validateCommonOperationCodeRepeat(String errorMessage,
      java.util.ArrayList<CommonOperation> ops) {
    StringBuilder sb = new StringBuilder();
    if (ops != null && ops.size() > 0) {
      for (int i = 0; i < ops.size() - 1; i++) {

        CommonOperation firstOperation = ops.get(i);
        for (int j = i + 1; j < ops.size(); j++) {

          CommonOperation secondOperation = ops.get(j);
          if (firstOperation.getCode().equals(secondOperation.getCode())) {
            String message = String
                .format(errorMessage + "'%1$s'与'%2$s'的编号重复。", firstOperation.getName(),
                    secondOperation.getName());
            sb.append("\n");
            return message;
          }
        }
      }
    }
    return sb.toString();
  }

//C#
  ///#endregion
}
